package com.itheima.service.impl;

import com.itheima.common.constant.MessageConstant;
import com.itheima.common.exception.DataNotFoundException;
import com.itheima.common.exception.FileUploadFailedException;
import com.itheima.common.utils.DateUtils;
import com.itheima.mapper.*;
import com.itheima.pojo.*;
import com.itheima.service.ReportService;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ReportServiceimpl implements ReportService {

    @Autowired
    ReportMapper reportMapper;
    @Autowired
    MemberMapper memberMapper;
    @Autowired
    SetmealMapper setmealMapper;
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderSettingMapper orderSettingMapper;

    @Override
    public ReportMemberVO getMemberReport() {
        /*
        //废案-------------------
        LocalDate today=LocalDate.now();
        List<Date>dates=new ArrayList<>();
        List<String>months=new ArrayList<>();
        List<Integer>memberCount=new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
        //DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy.MM.dd");
        List<Member>members=memberMapper.getAll();
        for(Member m:members){
            if(!dates.contains(m.getRegTime())){
                dates.add(m.getRegTime());

            }
        }
        Collections.sort(dates, new Comparator<Date>() {
            @Override
            public int compare(Date d1, Date d2) {
                return d1.compareTo(d2); // 按照日期的倒序排序
            }
        });
        for(Date date:dates){
             months.add(sdf.format(date));
             memberCount.add(memberMapper.CountMemeberByDate(date));
        }
        return new ReportMemberVO(months,memberCount);*/
        LocalDate today = LocalDate.now();
        List<String> months = new ArrayList<>();
        List<Integer> memberCount = new ArrayList<>();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy.MM.dd");
        for (int index = 11; index >= 0; index--) {
            // 获取截至次月第一天前的会员数量
            Integer count = memberMapper.selectMemberCountByMonth(today.plusMonths(1 - index).withDayOfMonth(1));
            memberCount.add(count);
            months.add(today.plusMonths(1 - index).withDayOfMonth(1).minusDays(1).format(df));
        }
        return new ReportMemberVO(months, memberCount);


    }

    @Override
    public ReportSetmealVO getSetmealReport() {
        List<Setmeal> setmeals = setmealMapper.getAll();
        if (setmeals.size() == 0) {
            throw new DataNotFoundException(MessageConstant.QUERY_SETMEAL_FAIL);
        }
        List<SetmealVO> setmealVOS = setmealMapper.getSetmealNameAndCount(null);
        return new ReportSetmealVO(setmealVOS.stream().map(SetmealVO::getName).collect(Collectors.toList()), setmealVOS);
    }

    @Override
    @Transactional
    public ReportBusinessData getBusinessReportData() {

        try {
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            //解决reportDate
            //解决thisMonthNewMember,thisWeekNewMember
            String reportDate=LocalDate.now().format(df);
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); // 定义日期格式
            Date date=DateUtils.parseString2Date(reportDate);
            //解决todayNewMember
            Integer todayNewMember=memberMapper.getCountByDate(date);
            //解决thisMonthNewMember,thisWeekNewMember
            Date MonthBeginDate=DateUtils.getFirstDay4ThisMonth();
            String MonthBeginStr=DateUtils.parseDate2String(MonthBeginDate);
            Integer thisMonthNewMember=memberMapper.getCountByMonth(MonthBeginStr);
            Date WeekBeginDate=DateUtils.getFirstDayOfWeek(date);
            String WeekBeginStr=DateUtils.parseDate2String(WeekBeginDate);
            Integer thisWeekNewMember=memberMapper.getCountByWeek(WeekBeginStr);
            //-----解决totalMember---------
            Integer totalMember=memberMapper.getAllCount();
            //------解决todayOrderNumber,thisMonthOrderNumber,thisWeekOrderNumber
            Integer todayOrderNumber=orderMapper.getCountByDate(date);
            Integer thisMonthOrderNumber =orderMapper.getCountByMonth(MonthBeginStr);
            Integer thisWeekOrderNumer=orderMapper.getCountByWeek(WeekBeginStr);
            //------解决todayVisitsNumber,thisMonthVisitsNumber,thisWeekVisitsNumber
            Integer todayVisitsNumber=orderMapper.getVisitsCountByDate(date,"已到诊");
            Integer thisMonthVisitsNumber=orderMapper.getVisitsCountByMonth(MonthBeginStr,"已到诊");
            Integer thisWeekVisitsNumber=orderMapper.getVisitsCountByWeek(WeekBeginStr,"已到诊");
            List<HotSetmeal>hotSetmeals=orderMapper.getHotSetmeals();

        //public ReportBusinessData( todayVisitsNumber,  reportDate,  todayNewMember,  thisWeekVisitsNumber, hotSetmeal,  thisMonthNewMember,  thisWeekNewMember,  totalMember,  thisMonthOrderNumber,  thisMonthVisitsNumber, int todayOrderNumber, int thisWeekOrderNumber)
            return new ReportBusinessData(todayVisitsNumber,reportDate,todayNewMember,thisWeekVisitsNumber,hotSetmeals,thisMonthNewMember,thisWeekNewMember,totalMember,thisMonthOrderNumber,thisMonthVisitsNumber,todayOrderNumber,thisWeekOrderNumer);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }





        /*------------废案-------------------------
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        //解决reportDate
        String reportDate=LocalDate.now().format(df);

        LocalDate date=LocalDate.parse(reportDate,df);
        //Date date1=Date.from(Instant.from(date));
        //解决todayNewMember
        Integer todayNewMember=memberMapper.getCountByDate(date);
        //解决thisMonthNewMember,thisWeekNewMember
        Integer year= date.getYear();
        Integer month=date.getMonthValue();
        Integer day= date.getDayOfMonth();

        Integer thisWeekNewMember=0;
        Integer thisMonthNewMember=0;
        List<Member>allMember=memberMapper.getAll();
        for(Member m:allMember){
            LocalDate localDate = m.getRegTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            //-------
            LocalDate firstDayOfWeek1 = date.with(TemporalAdjusters.previousOrSame(
                    WeekFields.of(Locale.getDefault()).getFirstDayOfWeek()));
            LocalDate firstDayOfWeek2 = localDate.with(TemporalAdjusters.previousOrSame(
                    WeekFields.of(Locale.getDefault()).getFirstDayOfWeek()));
            //----------
           if(year==m.getRegTime().getYear()+1990&&month==m.getRegTime().getMonth()+1){
               thisMonthNewMember++;
           }
           if(year==m.getRegTime().getYear()+1990&&month==m.getRegTime().getMonth()+1&&firstDayOfWeek1.equals(firstDayOfWeek2)){
               thisWeekNewMember++;
           }


        }
        //-----------------------------------------
        //-----解决totalMember---------
        Integer totalMember=memberMapper.getAllCount();
        //------解决todayOrderNumber,thisMonthOrderNumber,thisWeekOrderNumber
        Integer todayOrderNumber=0;
        Integer thisMonthOrderNumber=0;
        Integer thisWeekOrderNumber=0;
        List<OrderSetting>allOrderSetting=orderSettingMapper.getAll();
        for(OrderSetting orderSetting:allOrderSetting){
            LocalDate orderSettingLocalDate = orderSetting.getOrderDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            //-------
            LocalDate firstDayOfWeek1 = date.with(TemporalAdjusters.previousOrSame(
                    WeekFields.of(Locale.getDefault()).getFirstDayOfWeek()));
            LocalDate firstDayOfWeek2 = orderSettingLocalDate.with(TemporalAdjusters.previousOrSame(
                    WeekFields.of(Locale.getDefault()).getFirstDayOfWeek()));

            //----------
            if(year==orderSetting.getOrderDate().getYear()+1990&&month==orderSetting.getOrderDate().getMonth()+1&&day==orderSetting.getOrderDate().getDate()){
                todayOrderNumber+=orderSetting.getNumber();
            }
            if(year==orderSetting.getOrderDate().getYear()+1990&&month==orderSetting.getOrderDate().getMonth()+1){
                thisMonthOrderNumber+=orderSetting.getNumber();

            }
            if(year==orderSetting.getOrderDate().getYear()+1990&&month==orderSetting.getOrderDate().getMonth()+1&&firstDayOfWeek1.equals(firstDayOfWeek2)){
               thisWeekOrderNumber+=orderSetting.getNumber();
            }
        }
        //------解决todayVisitsNumber,thisMonthVisitsNumber,thisWeekVisitsNumber
        Integer todayVisitsNumber=0;
        Integer thisMonthVisitsNumber=0;
        Integer thisWeekVisitsNumber=0;
        // 200万
        List<Order>allOrders=orderMapper.getAll();
        for(Order order:allOrders){
            LocalDate orderLocalDate = order.getOrderDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            //-------
            LocalDate firstDayOfWeek1 = date.with(TemporalAdjusters.previousOrSame(
                    WeekFields.of(Locale.getDefault()).getFirstDayOfWeek()));
            LocalDate firstDayOfWeek2 = orderLocalDate.with(TemporalAdjusters.previousOrSame(
                    WeekFields.of(Locale.getDefault()).getFirstDayOfWeek()));

            //----------
            if(year==order.getOrderDate().getYear()+1990&&month==order.getOrderDate().getMonth()+1&&day==order.getOrderDate().getDate()){
               if(order.getOrderStatus()=="已到诊") todayVisitsNumber++;
            }
            if(year==order.getOrderDate().getYear()+1990&&month==order.getOrderDate().getMonth()+1){
                if(order.getOrderStatus()=="已到诊") thisMonthVisitsNumber++;

            }
            if(year==order.getOrderDate().getYear()+1990&&month==order.getOrderDate().getMonth()+1&&firstDayOfWeek1.equals(firstDayOfWeek2)){
                if(order.getOrderStatus()=="已到诊")  thisWeekVisitsNumber++;
            }

        }
        //---------------------

         */



      
    }

    @Override
    public void exportBusinessReport(HttpServletResponse response) {
    try{
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("templates/report_template.xlsx");
        ReportBusinessData reportBusinessData=getBusinessReportData();
        XSSFWorkbook excel=new XSSFWorkbook(is);
        XSSFSheet sheet=excel.getSheetAt(0);
        // 填充日期信息
        sheet.getRow(2).getCell(5).setCellValue(String.valueOf(reportBusinessData.getReportDate()));
        //填充其他信息
        sheet.getRow(4).getCell(5).setCellValue(reportBusinessData.getTodayNewMember());
        sheet.getRow(4).getCell(7).setCellValue(reportBusinessData.getTotalMember());
        sheet.getRow(5).getCell(5).setCellValue(reportBusinessData.getThisWeekNewMember());
        sheet.getRow(5).getCell(7).setCellValue(reportBusinessData.getThisMonthNewMember());
        // 填充今日相关数据
        sheet.getRow(7).getCell(5).setCellValue(reportBusinessData.getTodayOrderNumber());
        sheet.getRow(7).getCell(7).setCellValue(reportBusinessData.getTodayVisitsNumber());
        // 填充本周相关数据
        sheet.getRow(8).getCell(5).setCellValue(reportBusinessData.getThisWeekOrderNumber());
        sheet.getRow(8).getCell(7).setCellValue(reportBusinessData.getThisWeekVisitsNumber());
        // 填充本月相关数据
        sheet.getRow(9).getCell(5).setCellValue(reportBusinessData.getThisMonthOrderNumber());
        sheet.getRow(9).getCell(7).setCellValue(reportBusinessData.getThisMonthVisitsNumber());
        List<HotSetmeal> hotSetmeals = reportBusinessData.getHotSetmeal();
        for (int i = 0; i < hotSetmeals.size(); i++) {
            HotSetmeal item = hotSetmeals.get(i);
            sheet.getRow(12 + i).getCell(4).setCellValue(item.getName());
            sheet.getRow(12 + i).getCell(5).setCellValue(item.getSetmeal_count());
            sheet.getRow(12 + i).getCell(6).setCellValue(item.getProportion());
        }

        ServletOutputStream sos=response.getOutputStream();
        response.setContentType("application/vnd.ms-excel");
       excel.write(sos);
        excel.close();
        is.close();

    }catch (Exception e){

        throw  new FileUploadFailedException(MessageConstant.GET_SETMEAL_COUNT_REPORT_FAIL);
    }
    }
}
